package top.lingkang.mm.orm;

import top.lingkang.mm.error.MagicException;
import top.lingkang.mm.utils.MapParam;

import java.util.List;
import java.util.Map;

/**
 * 查询包装对象:
 * <pre>
 * {@code
 *     QueryWrapper<UserEntity> query = mapperManage.createQuery(
 *             "select * from t_user where id>#{id}",
 *             UserEntity.class);
 *     query.addParam("id", 2);
 *     List<UserEntity> list = query.getList();
 *     System.out.println(list);
 * }
 * </pre>
 *
 * @author lingkang
 * @create by 2024/3/5 16:33
 */
public class QueryWrapper<T> extends MapParam {
    private final String sql;
    private final Class<T> resultClass;
    private final MapperManageImpl manage;

    public QueryWrapper(String sql, Class<T> resultClass, MapperManageImpl manage) {
        this.sql = sql;
        this.resultClass = resultClass;
        this.manage = manage;
    }

    /**
     * 添加参数，sql中的参数只能用 #{paramName} <br>
     * 代码例子：
     * <pre>
     * {@code
     * QueryWrapper<UserEntity> query = mapperManage.createQuery(
     *                 "select * from t_user where id>#{id}",
     *                 UserEntity.class);
     *         query.addParam("id",2);// 参数 id
     *         List<UserEntity> list = query.getList();
     * }
     * </pre>
     *
     * @param name  参数名
     * @param value 参数值
     * @return 查询包装对象
     */
    public QueryWrapper<T> addParam(String name, Object value) {
        super.put(name, value);
        return this;
    }

    /**
     * 添加 map 参数
     *
     * @param params map参数
     * @return 查询包装对象
     */
    public QueryWrapper<T> addParam(Map<String, Object> params) {
        super.putAll(params);
        return this;
    }

    /**
     * 查询返回列表
     *
     * @return 查询结果，不为空。无结果时返回 new ArrayList<>()
     */
    public List<T> getList() {
        super.put("execSql_", sql);
        super.put("resType_", resultClass);
        return (List<T>) manage.langMapper.list(this);
    }

    /**
     * 查询一个对象，若结果有多个，会抛出异常
     *
     * @return 实体对象、null 等
     */
    public T getOne() {
        super.put("execSql_", sql);
        super.put("resType_", resultClass);
        List<T> list = manage.langMapper.list(this);
        if (list.isEmpty())
            return null;
        if (list.size() > 1)
            throw new MagicException("返回多个查询结果，请检查sql，此方法只能返回一个查询结果，实际返回结果数: " + list.size());
        return list.get(0);
    }

}
